package base.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;

/**
 * 文件工具jdk1.7↑
 * @author JZH
 *
 */
public class FileUtil {

	
	/**
	 * 复制文件
	 * @param source 源文件地址
	 * @param target 目的文件地址
	 * @param type 复制方式
	 * @throws IOException 
	 */
	public static void copy(String source, String target, CopyType type) throws IOException {
		copy(new File(source), target, type);
	}
	
	/**
	 * 复制文件
	 * @param file 目标文件
	 * @param target 目标地址
	 * @param type 复制方式
	 * @throws IOException 
	 */
	public static void copy(File file, String target, CopyType type) throws IOException {
		if(null != type) {
			if(CopyType.COPY_CHANNEL.equals(type)) {
				copyFileByFileChannel(new FileInputStream(file), target);
			} else if(CopyType.COPY_STREAM.equals(type)) {
				copyFileByStream(file, target);
			} else if(CopyType.COPY_APACHE.equals(type)) {
				copyFileByJava7(file, target);
			}
		}
	}
	
	/**
	 * 使用传统io流
	 * @param file
	 * @param target
	 */
	private static void copyFileByStream(File file, String target) {
		FileInputStream in = null;
		FileOutputStream out = null;
		BufferedInputStream bin = null;
		BufferedOutputStream bout = null;
		try {
			in = new FileInputStream(file);
			out = new FileOutputStream(file);
			bin = new BufferedInputStream(in);
			bout = new BufferedOutputStream(out);
			byte[] b = new byte[512];
			int size = -1;
			while((size = bin.read(b)) != -1) {
				bout.write(b, 0, size);
				bout.flush();
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if(null != bout) {
				try {
					bout.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(null != bin) {
				try {
					bin.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(null != out) {
				try {
					out.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(null != in) {
				try {
					in.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 使用Java7帶的方法
	 * @param file
	 * @param target
	 * @throws IOException
	 */
	private static void copyFileByJava7(File file, String target) throws IOException {
		Files.copy(file.toPath(), new File(target).toPath());
	}
	
	/**
	 * 使用NIO复制文件
	 * @param in
	 * @param target
	 */
	private static void copyFileByFileChannel(FileInputStream in, String target) {
		FileOutputStream out = null;
		FileChannel inChannel = null;
		FileChannel outChannel = null;
		try {
			out = new FileOutputStream(new File(target));
			inChannel = in.getChannel();
			outChannel = out.getChannel();
			ByteBuffer bf = ByteBuffer.allocate(2048);
			while(inChannel.read(bf) != -1) {
				bf.flip();
				outChannel.write(bf);
				bf.compact();
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			throw new RuntimeException(e);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			throw new RuntimeException(e);
		} finally {
			if(null != outChannel) {
				try {
					outChannel.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(null != inChannel) {
				try {
					inChannel.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(null != out) {
				try {
					out.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(null != in) {
				try {
					in.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	
	
	
	
	
	
	/**
	 * 复制文件的方式
	 * COPY_STREAM：使用传统的io流操作，速度较慢
	 * COPY_CHANNEL：使用nio操作，适合大文件，速度快
	 * COPY_APACHE：使用apache的commons io
	 * @author JZH
	 *
	 */
	public enum CopyType {  
		COPY_STREAM("COPY_STREAM"), COPY_CHANNEL("COPY_CHANNEL"), COPY_APACHE("COPY_APACHE");
		
		private String type;
		
		CopyType(String type) {
			this.type = type;
		}
		
		public String toString() {
			return type;
		}
	}  
	
}
